Ruby 日記 10日目: begin .. rescue .. else .. ensure
次のコードを実行するとどうなりますか
code:gold/ex10/main.rb
begin
print "liberty" + :fish
rescue TypeError
print "TypeError."
rescue
print "Error."
else
print "Else."
ensure
print "Ensure."
end
選択肢:
TypeError.Else.と表示される
TypeError.Ensure.と表示される
Ensure.と表示される
TypeError.と表示される
解説:
例外処理の話だね〜
code:rb
begin
式..
式..]..
[else
式..]
[ensure
式..]
end
本体の実行中に例外が発生した場合、rescue 節(複数指定できます)が 与えられていれば例外を捕捉できます。
発生した例外と一致する rescue 節が存在する時には rescue 節の本体が実行されます。
ふむふむ、そうだね
発生した例外は $! を使って参照することができます。
へぇ〜、$! 知らなかった
また、 指定されていれば変数 evar にも $! と同様に発生した例外が格 納されます。
これはよく使う
error_type が省略された時は StandardError のサブクラスであ る全ての例外を捕捉します
ふむ、そうだね
rescue では error_type は通常の引数と同じように評価され、 そのいずれかが一致すれば本体が実行されます。
そうだね
省略可能な else 節は、本体の実行によって例外が発生しなかった場合 に評価されます。
else節は例外が発生しなかった場合だけ評価される。そうだね
ensure 節が存在する時は begin 式を終了する直前に必ず ensure 節の本体を評価します。
ensure節の評価は最後。例外が起きても起きなくても必ず評価される。
begin式全体の評価値は、本体/rescue節/else節のうち 最後に評価された文の値です。
また各節において文が存在しなかったときの値 はnilです。
いずれにしてもensure節の値は無視されます。
ここ大事!ensure節は最後に必ず実行されるのだけど、begin式の全体の評価値には関与しない!
知らないとハマりそうなところだね
今回の問題に関してみていく
まず、StringとSymbolの足し算をしていて、これはTypeErrorになる
code:gold/ex10/type_error.rb
print "liberty" + :fish
ので "liberty" + :fish は print されない
code:sh
p# ruby gold/ex10/type_error.rb
gold/ex10/type_error.rb:1:in `+': no implicit conversion of Symbol into String (TypeError)
from gold/ex10/type_error.rb:1:in `<main>'
rescue TypeError しているので、print "TypeError." される
そのあとensure節が評価されるので、print "Ensure." される
よって答えは「TypeError.Ensure.と表示される」だね
code:sh
# ruby gold/ex10/main.rb
TypeError.Ensure.